const { Op } = require("sequelize");
const sequelize = require('sequelize');
const db = appRequire('db');

const userModel = appRequire('models/user');
const artPPTModel = appRequire('models/artPPT');
const orderModel = appRequire('models/order');
const downLoadModel = appRequire('models/downLoad');
const loginLogModel = appRequire('models/loginLog');

// 导出对象，供其它模块调用
module.exports = {
    getStatistics,
    getUserRegisterTrend,
    getUserLoginTrend,
    getDownloadTrend,
    getRevenueTrend,
    getTopPPTs
};

/**
 * 获取基础统计数据
 * 返回：总用户数、总课件数、累计收益、总下载量
 */
async function getStatistics(req, res) {
    try {
        const returnData = Common.clone(Constant.DEFAULT_SUCCESS);

        // 获取总用户数
        const totalUsers = await userModel.user.count();

        // 获取总课件数
        const totalPPTs = await artPPTModel.count();

        // 获取累计收益（已支付且金额>0的订单）
        const totalRevenue = await orderModel.order.sum('payMoney', {
            where: {
                status: 1,
                payMoney: { [Op.gt]: 0 },
                type: [1, 2]
            }
        }) || 0;

        // 获取总下载量
        const totalDownloads = await downLoadModel.downLoad.count();

        returnData.data = {
            totalUsers,
            totalPPTs,
            totalRevenue: parseFloat(totalRevenue.toFixed(2)),
            totalDownloads
        };

        return res.json(returnData);
    } catch (error) {
        console.error('获取统计数据错误:', error);
        const errorData = Common.clone(Constant.DEFAULT_ERROR);
        errorData.msg = '获取统计数据失败: ' + error.message;
        return res.json(errorData);
    }
}

/**
 * 获取用户注册趋势（最近7天）
 * 返回：日期数组和对应的注册人数
 */
async function getUserRegisterTrend(req, res) {
    try {
        const returnData = Common.clone(Constant.DEFAULT_SUCCESS);

        // 计算7天前的日期
        const today = new Date();
        const sevenDaysAgo = new Date(today);
        sevenDaysAgo.setDate(today.getDate() - 6);
        sevenDaysAgo.setHours(0, 0, 0, 0);

        // 按日期分组统计
        const result = await userModel.user.findAll({
            attributes: [
                [sequelize.fn('DATE', sequelize.col('createdAt')), 'date'],
                [sequelize.fn('COUNT', sequelize.col('objectId')), 'count']
            ],
            where: {
                createdAt: {
                    [Op.gte]: sevenDaysAgo
                }
            },
            group: [sequelize.fn('DATE', sequelize.col('createdAt'))],
            order: [[sequelize.fn('DATE', sequelize.col('createdAt')), 'ASC']],
            raw: true
        });

        // 生成完整的7天日期数组（即使某天没有数据也要显示0）
        const dates = [];
        const values = [];
        for (let i = 0; i < 7; i++) {
            const date = new Date(sevenDaysAgo);
            date.setDate(sevenDaysAgo.getDate() + i);
            // 使用本地时间格式化日期，避免时区问题
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const dateStr = `${year}-${month}-${day}`;
            dates.push(dateStr);

            const found = result.find(item => item.date === dateStr);
            values.push(found ? parseInt(found.count) : 0);
        }

        returnData.data = {
            dates,
            values
        };

        return res.json(returnData);
    } catch (error) {
        console.error('获取用户注册趋势错误:', error);
        const errorData = Common.clone(Constant.DEFAULT_ERROR);
        errorData.msg = '获取用户注册趋势失败: ' + error.message;
        return res.json(errorData);
    }
}

/**
 * 获取用户登录趋势（最近7天）
 * 返回：日期数组和对应的登录人数（去重）
 */
async function getUserLoginTrend(req, res) {
    try {
        const returnData = Common.clone(Constant.DEFAULT_SUCCESS);

        // 计算7天前的日期
        const today = new Date();
        const sevenDaysAgo = new Date(today);
        sevenDaysAgo.setDate(today.getDate() - 6);
        sevenDaysAgo.setHours(0, 0, 0, 0);

        // 按日期分组统计（统计每天的独立登录用户数）
        const result = await loginLogModel.loginLog.findAll({
            attributes: [
                [sequelize.fn('DATE', sequelize.col('loginTime')), 'date'],
                [sequelize.fn('COUNT', sequelize.fn('DISTINCT', sequelize.col('userId'))), 'count']
            ],
            where: {
                loginTime: {
                    [Op.gte]: sevenDaysAgo
                }
            },
            group: [sequelize.fn('DATE', sequelize.col('loginTime'))],
            order: [[sequelize.fn('DATE', sequelize.col('loginTime')), 'ASC']],
            raw: true
        });

        // 生成完整的7天日期数组
        const dates = [];
        const values = [];
        for (let i = 0; i < 7; i++) {
            const date = new Date(sevenDaysAgo);
            date.setDate(sevenDaysAgo.getDate() + i);
            // 使用本地时间格式化日期，避免时区问题
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const dateStr = `${year}-${month}-${day}`;
            dates.push(dateStr);

            const found = result.find(item => item.date === dateStr);
            values.push(found ? parseInt(found.count) : 0);
        }

        returnData.data = {
            dates,
            values
        };

        return res.json(returnData);
    } catch (error) {
        console.error('获取用户登录趋势错误:', error);
        const errorData = Common.clone(Constant.DEFAULT_ERROR);
        errorData.msg = '获取用户登录趋势失败: ' + error.message;
        return res.json(errorData);
    }
}

/**
 * 获取课件下载趋势（最近7天）
 * 返回：日期数组和对应的下载次数
 */
async function getDownloadTrend(req, res) {
    try {
        const returnData = Common.clone(Constant.DEFAULT_SUCCESS);

        // 计算7天前的日期
        const today = new Date();
        const sevenDaysAgo = new Date(today);
        sevenDaysAgo.setDate(today.getDate() - 6);
        sevenDaysAgo.setHours(0, 0, 0, 0);

        // 按日期分组统计
        const result = await downLoadModel.downLoad.findAll({
            attributes: [
                [sequelize.fn('DATE', sequelize.col('createdAt')), 'date'],
                [sequelize.fn('COUNT', sequelize.col('objectId')), 'count']
            ],
            where: {
                createdAt: {
                    [Op.gte]: sevenDaysAgo
                }
            },
            group: [sequelize.fn('DATE', sequelize.col('createdAt'))],
            order: [[sequelize.fn('DATE', sequelize.col('createdAt')), 'ASC']],
            raw: true
        });

        // 生成完整的7天日期数组
        const dates = [];
        const values = [];
        for (let i = 0; i < 7; i++) {
            const date = new Date(sevenDaysAgo);
            date.setDate(sevenDaysAgo.getDate() + i);
            // 使用本地时间格式化日期，避免时区问题
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const dateStr = `${year}-${month}-${day}`;
            dates.push(dateStr);

            const found = result.find(item => item.date === dateStr);
            values.push(found ? parseInt(found.count) : 0);
        }

        returnData.data = {
            dates,
            values
        };

        return res.json(returnData);
    } catch (error) {
        console.error('获取下载趋势错误:', error);
        const errorData = Common.clone(Constant.DEFAULT_ERROR);
        errorData.msg = '获取下载趋势失败: ' + error.message;
        return res.json(errorData);
    }
}

/**
 * 获取收益趋势（最近7天）
 * 返回：日期数组和对应的收益金额
 */
async function getRevenueTrend(req, res) {
    try {
        const returnData = Common.clone(Constant.DEFAULT_SUCCESS);

        // 计算7天前的日期
        const today = new Date();
        const sevenDaysAgo = new Date(today);
        sevenDaysAgo.setDate(today.getDate() - 6);
        sevenDaysAgo.setHours(0, 0, 0, 0);

        // 按日期分组统计收益
        const result = await orderModel.order.findAll({
            attributes: [
                [sequelize.fn('DATE', sequelize.col('createdAt')), 'date'],
                [sequelize.fn('SUM', sequelize.col('payMoney')), 'total']
            ],
            where: {
                createdAt: {
                    [Op.gte]: sevenDaysAgo
                },
                status: 1,
                payMoney: { [Op.gt]: 0 },
                type: [1, 2]
            },
            group: [sequelize.fn('DATE', sequelize.col('createdAt'))],
            order: [[sequelize.fn('DATE', sequelize.col('createdAt')), 'ASC']],
            raw: true
        });

        // 生成完整的7天日期数组
        const dates = [];
        const values = [];
        for (let i = 0; i < 7; i++) {
            const date = new Date(sevenDaysAgo);
            date.setDate(sevenDaysAgo.getDate() + i);
            // 使用本地时间格式化日期，避免时区问题
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const dateStr = `${year}-${month}-${day}`;
            dates.push(dateStr);

            const found = result.find(item => item.date === dateStr);
            values.push(found ? parseFloat(parseFloat(found.total).toFixed(2)) : 0);
        }

        returnData.data = {
            dates,
            values
        };

        return res.json(returnData);
    } catch (error) {
        console.error('获取收益趋势错误:', error);
        const errorData = Common.clone(Constant.DEFAULT_ERROR);
        errorData.msg = '获取收益趋势失败: ' + error.message;
        return res.json(errorData);
    }
}

/**
 * 获取热门课件TOP 5
 * 返回：下载量最多的前5个课件
 */
async function getTopPPTs(req, res) {
    try {
        const returnData = Common.clone(Constant.DEFAULT_SUCCESS);

        // 按课件ID分组统计下载次数，并关联课件信息
        const result = await downLoadModel.downLoad.findAll({
            attributes: [
                'artpptId',
                [sequelize.fn('COUNT', sequelize.col('downLoad.objectId')), 'downloadCount']
            ],
            include: [{
                model: artPPTModel,
                as: 'artPPT',
                attributes: ['objectId', 'title', 'desc'],
            }],
            group: ['artpptId'],
            order: [[sequelize.fn('COUNT', sequelize.col('downLoad.objectId')), 'DESC']],
            limit: 5,
            raw: false
        });

        const data = result.map(item => {
            const plainItem = item.get({ plain: true });
            return {
                pptId: plainItem.artpptId,
                title: plainItem.artPPT ? plainItem.artPPT.title : '未知课件',
                desc: plainItem.artPPT ? plainItem.artPPT.desc : '',
                downloadCount: parseInt(plainItem.downloadCount)
            };
        });

        returnData.data = data;

        return res.json(returnData);
    } catch (error) {
        console.error('获取热门课件错误:', error);
        const errorData = Common.clone(Constant.DEFAULT_ERROR);
        errorData.msg = '获取热门课件失败: ' + error.message;
        return res.json(errorData);
    }
}
